#pragma once

#include <string>
using std::string;
#include <Windows.h>
#include <basetsd.h>
#include <windef.h>
#define GET_UINT32(n,b,i) {(n) = ( (UINT32) (b)[(i)] << 24 )| ( (UINT32) (b)[(i) + 1] << 16 ) | ( (UINT32) (b)[(i) + 2] <<  8 ) | ( (UINT32) (b)[(i) + 3]); }   
#define PUT_UINT32(n,b,i)  {(b)[(i)] = (UINT8) ( (n) >> 24 );(b)[(i) + 1] = (UINT8) ( (n) >> 16 );(b)[(i) + 2] = (UINT8) ( (n) >>  8 );(b)[(i) + 3] = (UINT8) ( (n) );}   

typedef struct
{
	UINT32 total[2];
	UINT32 state[5];
	UINT8 buffer[64];
}SHA1_CONTEXT;

UINT8 const sha1_padding[64] =
{
	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

class CSHA1
{
public:
	CSHA1(void);
	~CSHA1(void);

	enum {
		SHA1_DIGEST_LENGTH = 20,
		SHA1_BLOCK_SIZE = 64,
		HMAC_BUF_LEN = 4096
	};

	void OnSha1Enctrypt(const char* szFilePath, BYTE* szRet);
	void OnSha1_Starts(SHA1_CONTEXT* ctx);
	void OnSha1_Update(SHA1_CONTEXT* ctx, UINT8* input, UINT32 length);
	void OnSha1_Finish(SHA1_CONTEXT* ctx, UINT8 digest[20]);
	void OnSha1_Process(SHA1_CONTEXT* ctx, UINT8 data[64]);
};

